package com.itheima.app.manager;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.Movement;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.MovementVo;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class MovementMananger {

    @DubboReference
    MovementService movementService;

    @Autowired
    OssTemplate ossTemplate;

    @DubboReference
    UserInfoService userInfoService;

    @DubboReference
    CommentService commentService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    MQMovementManager mqMovementManager;

    public ResponseEntity save(Movement movement, MultipartFile[] imageContent) throws IOException {
        //1.将所有图片上传到阿里云,将这些地址存放一个list中
        List<String> imgList = new ArrayList<>();
        if (ArrayUtil.isNotEmpty(imageContent)) {
            for (MultipartFile multipartFile : imageContent) {
                String url = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                imgList.add(url);
            }
        }

        //2.封装动态(发布人,动态id,发布时间.)
        movement.setId(ObjectId.get());
        movement.setUserId(UserHolder.get().getId());//发布人(当前登陆者)
        movement.setMedias(imgList);//文件列表
        movement.setState(0);//审核状态
        movement.setCreated(System.currentTimeMillis());//发布时间
        movement.setSeeType(1);//此版本暂时没有实现

        //3.远程调用service完成发布操作
        movementService.save(movement);

        //4.往mq中发送一条数据,数据内容就是动态的id
        rabbitTemplate.convertAndSend("tanhua.movement.state",movement.getId().toString());

        //5.往mq中发送一条数据,用户推荐系统
        mqMovementManager.sendMovement(UserHolder.get().getId(),movement.getId(),MQMovementManager.MOVEMENT_PUBLISH);

        return ResponseEntity.ok(null);
    }

    public ResponseEntity findMyMovementByPage(Long userId, Integer pageNum, Integer pageSize) {
        //1.远程调用service查询分页数据
        PageBeanVo pageBeanVo = movementService.findMyMovementByPage(userId, pageNum, pageSize);

        //2.查询当前用户的userInfo
        UserInfo userInfo = userInfoService.findByUserId(userId);

        //3.获取分页数据中的list,遍历,获取每个动态详情
        //3.1 创建movementVo集合
        List<MovementVo> voList = new ArrayList<>();

        //3.2 获取分页数据中的list,遍历
        List<Movement> items = (List<Movement>) pageBeanVo.getItems();
        if (CollUtil.isNotEmpty(items)) {
            for (Movement movement : items) {
                //4.封装MovementVo对象(userInfo+movement),将对象放入vo集合中
                MovementVo vo = new MovementVo();

                //切记:先封装userInfo,再封装movement
                vo.setUserInfo(userInfo);
                vo.setMovement(movement);

                //封装是否点赞
                if(stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId().toString()))){
                    vo.setHasLiked(1);
                }

                voList.add(vo);
            }
        }

        //5.将vo集合设置给pageBeanVo且返回
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    public ResponseEntity findFriendMovementByPage(Integer pageNum, Integer pageSize) {
        //1.获取登陆者id
        Long userId = UserHolder.get().getId();

        //2.远程调用service查询好友动态数据
        PageBeanVo pageBeanVo = movementService.findFriendMovementByPage(userId, pageNum, pageSize);

        //3.获取动态数据list,遍历,获取每个动态,通过动态发布者id查询userInfo
        //3.1 创建movementVo集合
        List<MovementVo> voList = new ArrayList<>();

        //3.2 获取分页数据list,遍历
        List<Movement> items = (List<Movement>) pageBeanVo.getItems();
        if (CollUtil.isNotEmpty(items)) {
            for (Movement movement : items) {
                //3.3 获取每个动态发布者id 查询userInfo
                UserInfo userInfo = userInfoService.findByUserId(movement.getUserId());


                //4.封装MovementVo对象,放入vo集合中
                MovementVo vo = new MovementVo();

                //先userInfo 后movement
                vo.setUserInfo(userInfo);
                vo.setMovement(movement);

                //封装是否点赞
                if(stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId().toString()))){
                    vo.setHasLiked(1);
                }

                voList.add(vo);
            }
        }

        //5.将vo集合设置给pageBeanVo且返回
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    public ResponseEntity findRecommendMovementByPage(Integer pageNum, Integer pageSize) {
        //1.获取登陆者id
        Long userId = UserHolder.get().getId();

        //2.远程调用service查询推荐动态数据
        PageBeanVo pageBeanVo = movementService.findRecommendMovementByPage(userId, pageNum, pageSize);

        //3.获取动态数据list,遍历,获取每个动态,通过动态发布者id查询userInfo
        //3.1 创建movementVo集合
        List<MovementVo> voList = new ArrayList<>();

        //3.2 获取分页数据list,遍历
        List<Movement> items = (List<Movement>) pageBeanVo.getItems();
        if (CollUtil.isNotEmpty(items)) {
            for (Movement movement : items) {
                //3.3 获取每个动态发布者id 查询userInfo
                UserInfo userInfo = userInfoService.findByUserId(movement.getUserId());

                //4.封装MovementVo对象,放入vo集合中
                MovementVo vo = new MovementVo();

                //先userInfo 后movement
                vo.setUserInfo(userInfo);
                vo.setMovement(movement);

                //封装是否点赞
                if(stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId().toString()))){
                    vo.setHasLiked(1);
                }

                //封装是否喜欢
                if(stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LOVE,userId,movement.getId().toString()))){
                    vo.setHasLoved(1);
                }

                voList.add(vo);
            }
        }

        //5.将vo集合设置给pageBeanVo且返回
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    public ResponseEntity movementLike(String publishId) {
        //1.远程调用service查询该动态
        Movement movement = movementService.findById(new ObjectId(publishId));

        //2.封装Comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1);//点赞
        comment.setUserId(UserHolder.get().getId());
        comment.setPublishUserId(movement.getUserId());//动态的发布人id

        //3.远程调用service完成保存操作
        Integer count = commentService.saveComment(comment);

        //4.标记当前用户对动态的操作(那个用户对那条动态点赞)
        //stringRedisTemplate.opsForValue().set("movement_like:用户id_动态id","1");
        stringRedisTemplate.opsForValue().
                set(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,UserHolder.get().getId(),publishId),"1");

        //5.给mq发送一条消息
        mqMovementManager.sendMovement(UserHolder.get().getId(),movement.getId(),MQMovementManager.MOVEMENT_LIKE);

        return ResponseEntity.ok(count);
    }

    public ResponseEntity movementDislike(String publishId) {
        //1.远程调用service完成删除操作
        Integer count = commentService.removeComment(UserHolder.get().getId(), new ObjectId(publishId), 1);
        //2.删除redis中对这条动态的点赞操作
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,UserHolder.get().getId(),publishId));

        //5.给mq发送一条消息
        mqMovementManager.sendMovement(UserHolder.get().getId(),new ObjectId(publishId),MQMovementManager.MOVEMENT_DISLIKE);
        return ResponseEntity.ok(count);
    }

    public ResponseEntity movementLove(String publishId) {
        //1.远程调用service查询该动态
        Movement movement = movementService.findById(new ObjectId(publishId));

        //2.封装Comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(3);//喜欢
        comment.setUserId(UserHolder.get().getId());
        comment.setPublishUserId(movement.getUserId());//动态的发布人id

        //3.远程调用service完成保存操作
        Integer count = commentService.saveComment(comment);

        //4.标记当前用户对动态的操作(那个用户对那条动态喜欢)
        //stringRedisTemplate.opsForValue().set("movement_love:用户id_动态id","1");
        stringRedisTemplate.opsForValue().
                set(StrUtil.format(ConstantUtil.MOVEMENT_LOVE,UserHolder.get().getId(),publishId),"1");

        //5.给mq发送一条消息
        mqMovementManager.sendMovement(UserHolder.get().getId(),movement.getId(),MQMovementManager.MOVEMENT_LOVE);

        return ResponseEntity.ok(count);
    }

    public ResponseEntity movementUnlove(String publishId) {
        //1.远程调用service完成删除操作
        Integer count = commentService.removeComment(UserHolder.get().getId(), new ObjectId(publishId), 3);
        //2.删除redis中对这条动态的喜欢操作
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LOVE,UserHolder.get().getId(),publishId));

        //5.给mq发送一条消息
        mqMovementManager.sendMovement(UserHolder.get().getId(),new ObjectId(publishId),MQMovementManager.MOVEMENT_DISLOVE);
        return ResponseEntity.ok(count);
    }

    //查询单条动态
    public ResponseEntity findById(String publishId) {
        //1.远程调用service查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));

        //2.获取动态的发布人id,远程调用service查询userInfo
        UserInfo userInfo = userInfoService.findByUserId(movement.getUserId());

        //3.封装movementVo且返回
        MovementVo vo = new MovementVo();
        vo.setUserInfo(userInfo);
        vo.setMovement(movement);

        //5.给mq发送一条消息
        mqMovementManager.sendMovement(UserHolder.get().getId(),new ObjectId(publishId),MQMovementManager.MOVEMENT_BROWSE);

        return ResponseEntity.ok(vo);
    }

    public ResponseEntity findCommentByPage(String publishId, Integer pageNum, Integer pageSize) {
        //1.远程调用service查询当前页数据
        PageBeanVo pageBeanVo = commentService.findCommentByPage(new ObjectId(publishId), pageNum, pageSize);

        //2.遍历分页中评论列表,获取每个评论,通过评论获取评论发布人id
        //2.1创建一个voList
        List<CommentVo> voList = new ArrayList<>();

        //2.2遍历分页中评论列表,获取每个评论
        List<Comment> items = (List<Comment>) pageBeanVo.getItems();
        if (CollUtil.isNotEmpty(items)) {
            for (Comment comment : items) {
                //3通过用户id查询userInfo
                UserInfo userInfo = userInfoService.findByUserId(comment.getUserId());

                //4.将每个评论和userInfo封装成CommentVo对象,放入vo集合中
                CommentVo vo = new CommentVo();
                vo.setId(comment.getId().toString());
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                vo.setContent(comment.getContent());
                vo.setCreateDate(DateUtil.formatDateTime(new Date(comment.getCreated())));
                vo.setLikeCount(comment.getLikeCount());//暂时没有做

                voList.add(vo);
            }
        }

        //5.将vo集合设置给pageBeanVo且返回
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    public ResponseEntity saveMovementComment(String publishId, String content) {
        //1.远程调用service查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        
        //2.封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(2);
        comment.setUserId(UserHolder.get().getId());
        comment.setPublishUserId(movement.getUserId());
        comment.setContent(content);

        //3.远程调用service完成保存操作
        Integer count = commentService.saveComment(comment);

        //5.给mq发送一条消息
        mqMovementManager.sendMovement(UserHolder.get().getId(),new ObjectId(publishId),MQMovementManager.MOVEMENT_COMMENT);
        return ResponseEntity.ok(count);
    }
}
